package cn.xorange.commons.utils.id;

import cn.hutool.core.lang.ObjectId;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.lang.UUID;
import cn.xorange.commons.utils.configuration.UtilsProperties;
import cn.xorange.commons.utils.codec.BaseUtils;
import cn.xorange.commons.utils.lang.ObjectUtils;
import cn.xorange.commons.utils.spring.SpringUtils;

import java.security.SecureRandom;
import java.util.Date;
import java.util.Random;

public class IdUtils {
    private IdUtils(){}

    private static SecureRandom random = new SecureRandom();


    /**
     * 生成类似于：b17f24ff026d40949c85a24f4f375d42(32位)
     **/
    public static String fastSimpleUUID(){
        return UUID.fastUUID().toString(true);
    }

    /**
     * ObjectId是MongoDB数据库的一种唯一ID生成策略，是UUID version1的变种
     * 生成类似：5b9e306a4df4f8c54a39fb0c（24位）
     */
    public static String objectId(){
        return ObjectId.next();
    }

    public static long snowflake(){
        UtilsProperties utilsProperties = SpringUtils.getBean(UtilsProperties.class);
        Long workerId = ObjectUtils.toLong(utilsProperties.getSnowflakeMachineBit());
        Long datacenterId = ObjectUtils.toLong(utilsProperties.getSnowflakeDatacenterBit() );
        Snowflake snowflake = cn.hutool.core.util.IdUtil.getSnowflake(workerId,datacenterId);
        return snowflake.nextId();
    }

    /**
     * 基于Base32编码的SecureRandom随机生成bytes.
     */
    public static String randomBase32(int length) {
        byte[] randomBytes = new byte[length];
        random.nextBytes(randomBytes);
        return BaseUtils.encodeBase32(randomBytes);
    }

    /**
     *
     * Description:获取指定长度随机数 <br>
     *
     * @param stringLength 字符串长度
     * @return <br>
     */
    public static String randomNum(int stringLength) {
        Random random = new Random();
        double pros = (1 + random.nextDouble()) * Math.pow(10, stringLength);
        String result = String.valueOf(pros);
        return result.substring(1, stringLength + 1);

    }

    /**
     * Description:按照时间长度取固定长度的流水号 <br>
     *
     * @param pref 前缀
     * @param length 长度
     * @return <br>
     */
    public static String getSerialByDate(String pref, int length) {
        StringBuilder sb = new StringBuilder();
        sb.append(pref);
        String nowDateString = cn.hutool.core.date.DateUtil.format(new Date(), "yyyyMMddHHmmss");
        sb.append(nowDateString);
        if (sb.length() < length) {
            int need = length - sb.length();
            String needString = randomNum(need);
            sb.append(needString);
            return sb.toString();
        } else if (sb.length() > length) {
            return sb.substring(0, length);
        } else {
            return sb.toString();
        }
    }


}
